﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Be.Timvw.Framework.Domain.Ranges
{
    /// <summary>
    /// Specifications for the comparison of ranges.
    /// </summary>
    [TestClass]
    public class WhenComparingRanges
    {
        /// <summary>
        /// Should return zero when both ranges have same period.
        /// </summary>
        [TestMethod]
        public void ShouldReturnZeroWhenBothRangesHaveSamePeriod()
        {
            Range<DateTime> range1 = RangeFactory.GetRangeForDaysFromFirstJanuary2000(100);
            Range<DateTime> range2 = RangeFactory.GetRangeForDaysFromFirstJanuary2000(100);
            Assert.AreEqual(0, range1.CompareTo(range2));
        }

        /// <summary>
        /// Should return negative when first period begins before second period.
        /// </summary>
        [TestMethod]
        public void ShouldReturnNegativeWhenFirstPeriodBeginsBeforeSecondPeriod()
        {
            Range<DateTime> range1 = RangeFactory.GetRangeForDaysFromFirstJanuary2000(100);
            Range<DateTime> range2 = new Range<DateTime>(new DateTime(2008, 1, 1), new DateTime(2008, 12, 31));
            Assert.IsTrue(range1.CompareTo(range2) < 0);
        }

        /// <summary>
        /// When two periods start at the same time, the end should be considered.
        /// </summary>
        [TestMethod]
        public void ShouldReturnPositiveWhenSecondPeriodEndsBeforeFirstPeriod()
        {
            Range<DateTime> range1 = RangeFactory.GetRangeForDaysFromFirstJanuary2000(150);
            Range<DateTime> range2 = RangeFactory.GetRangeForDaysFromFirstJanuary2000(100);
            Assert.IsTrue(range1.CompareTo(range2) > 0);
        }

        /// <summary>
        /// Should return zero when both ranges reference the same instance.
        /// </summary>
        [TestMethod]
        public void ShouldReturnZeroWhenBothArgumentsReferenceSameInstance()
        {
            Range<DateTime> range = RangeFactory.GetRangeForDaysFromFirstJanuary2000(150);
            Range<DateTime> range1 = range;
            Range<DateTime> range2 = range;
            Assert.IsTrue(range1.CompareTo(range2) == 0);
        }

        /// <summary>
        /// Smaller than operator should return true when first argument is null.
        /// </summary>
        [TestMethod]
        public void ShouldReturnTrueForSmallerThanOperatorTrueWhenFirstArgumentIsNull()
        {
            Range<DateTime> range1 = null;
            Range<DateTime> range2 = RangeFactory.GetRangeForDaysFromFirstJanuary2000(100);
            Assert.IsTrue(range1 < range2);
            Assert.IsFalse(range1 > range2);
        }

        /// <summary>
        /// Smaller than operator should return false when second argument is null.
        /// </summary>
        [TestMethod]
        public void ShouldReturnFalseForSmallerThanOperatorWhenSecondArgumentIsNull()
        {
            Range<DateTime> range1 = RangeFactory.GetRangeForDaysFromFirstJanuary2000(100);
            Range<DateTime> range2 = null;
            Assert.IsFalse(range1 < range2);
            Assert.IsTrue(range1 > range2);
        }
    }
}